#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# cron: 30 22 * * *
# new Env("爱路桥任务每日统计")

import os
import re
import glob
import json
import logging
import requests
from datetime import datetime, timedelta
from collections import defaultdict

# 配置日志格式
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger("AiLuQiaoStats")

# ====================== 配置区域 ======================
LOG_DIR_PATTERN = "/ql/data/log/XiaoMao_爱路桥*"  # 日志目录模式（支持通配符）
TIME_RANGE_HOURS = 24  # 分析最近多少小时的日志
DEBUG_MODE = False      # 设置为True启用详细调试日志
REPORT_FILE = "/ql/data/log/Message/PUSH_ALQ.log"  # 报告保存路径
# =====================================================

# 在logger定义后设置调试模式
if DEBUG_MODE:
    logger.setLevel(logging.DEBUG)
    logger.debug("调试模式已启用")

def parse_alq_logs(log_content, account_data):
    """
    解析爱路桥任务日志内容并提取统计信息
    """
    # 编译正则表达式 - 爱路桥特定格式
    account_section_pattern = re.compile(r'👤\s*账号\s*\d+/\d+:\s*(\d+)')
    account_points_pattern = re.compile(r'🏆\s*当前积分[:：]\s*(\d+)')
    lottery_result_pattern = re.compile(r'🎉\s*抽奖获得[:：]\s*([\d.]+)元')
    task_progress_pattern = re.compile(r'📌\s*([^:]+?)\s*[:：]\s*进度\((\d+)/(\d+)\)')
    article_read_pattern = re.compile(r'📄\s*文章\(\d+/\d+\):\s*✅\s*阅读成功')
    news_task_pattern = re.compile(r'📄\s*新闻\(\d+/\d+\):\s*(.+)')
    task_result_pattern = re.compile(r'(👀|👍|🔄)\s*(阅读任务|点赞任务|转发任务)\s*[:：]\s*(✅|❌)\s*(成功|失败)(?:【(.*?)】)?')
    
    current_account = None
    lines = log_content.split('\n')
    
    for line in lines:
        # 宽松处理空行
        if not line.strip():
            continue
            
        # 调试日志：打印处理的行
        logger.debug(f"处理行: {line}")
            
        # 检测账号区块开始 - 爱路桥格式
        section_match = account_section_pattern.search(line)
        if section_match:
            current_account = section_match.group(1)
            if current_account not in account_data:
                account_data[current_account] = {
                    'points': 0,
                    'lottery_amount': 0.0,
                    'tasks': defaultdict(lambda: {'completed': 0, 'total': 0}),
                    'articles_read': 0,
                    'total_articles': 0,
                    'news_tasks': {
                        'read': {'success': 0, 'fail': 0},
                        'like': {'success': 0, 'fail': 0},
                        'share': {'success': 0, 'fail': 0}
                    }
                }
            logger.debug(f"检测到账号区块: {current_account}")
            continue
            
        if not current_account:
            continue
            
        # 提取积分信息
        points_match = account_points_pattern.search(line)
        if points_match:
            points = int(points_match.group(1))
            account_data[current_account]['points'] = points
            logger.debug(f"{current_account} 积分: {points}")
            continue
            
        # 提取抽奖结果
        lottery_match = lottery_result_pattern.search(line)
        if lottery_match:
            amount = float(lottery_match.group(1))
            account_data[current_account]['lottery_amount'] = amount
            logger.debug(f"{current_account} 抽奖获得红包: {amount}元")
            continue
            
        # 提取文章阅读统计
        article_match = article_read_pattern.search(line)
        if article_match:
            account_data[current_account]['articles_read'] += 1
            account_data[current_account]['total_articles'] = max(
                account_data[current_account]['total_articles'],
                account_data[current_account]['articles_read']
            )
            logger.debug(f"{current_account} 文章阅读成功")
            continue
            
        # 提取任务进度
        task_progress_match = task_progress_pattern.search(line)
        if task_progress_match:
            task_name = task_progress_match.group(1).strip()
            completed = int(task_progress_match.group(2))
            total = int(task_progress_match.group(3))
            
            # 特殊处理分享用户任务
            if "分享用户" in task_name:
                task_name = "分享用户"
                
            account_data[current_account]['tasks'][task_name]['completed'] = completed
            account_data[current_account]['tasks'][task_name]['total'] = total
            logger.debug(f"{current_account} 任务[{task_name}]进度: {completed}/{total}")
            continue
            
        # 提取新闻任务结果
        news_match = news_task_pattern.search(line)
        if news_match:
            news_title = news_match.group(1)
            logger.debug(f"{current_account} 处理新闻: {news_title}")
            continue
            
        # 提取具体任务结果（阅读、点赞、转发）
        task_result_match = task_result_pattern.search(line)
        if task_result_match:
            task_type = task_result_match.group(2)
            status = task_result_match.group(3)
            reason = task_result_match.group(5) or ""
            
            if task_type == "阅读任务":
                key = 'read'
            elif task_type == "点赞任务":
                key = 'like'
            elif task_type == "转发任务":
                key = 'share'
            else:
                continue
                
            if status == "✅":
                account_data[current_account]['news_tasks'][key]['success'] += 1
                logger.debug(f"{current_account} {task_type} 成功")
            else:
                account_data[current_account]['news_tasks'][key]['fail'] += 1
                logger.debug(f"{current_account} {task_type} 失败: {reason}")
    
    return account_data

def process_log_directories():
    """
    处理日志目录并解析所有匹配的日志文件
    返回账号统计数据
    """
    # 计算时间范围（最近N小时）
    time_threshold = datetime.now() - timedelta(hours=TIME_RANGE_HOURS)
    logger.info(f"分析时间范围: {time_threshold.strftime('%Y-%m-%d %H:%M:%S')} 至今")
    
    account_data = {}
    processed_files = 0
    skipped_files = 0
    
    # 获取所有匹配的日志文件（按时间倒序）
    all_files = []
    for log_dir in glob.glob(LOG_DIR_PATTERN):
        if not os.path.isdir(log_dir):
            continue
            
        for filename in os.listdir(log_dir):
            if filename.endswith('.log'):
                file_path = os.path.join(log_dir, filename)
                file_mtime = datetime.fromtimestamp(os.path.getmtime(file_path))
                all_files.append((file_path, file_mtime))
    
    # 按修改时间倒序排序
    all_files.sort(key=lambda x: x[1], reverse=True)
    
    # 处理日志文件
    for file_path, file_mtime in all_files:
        if file_mtime < time_threshold:
            skipped_files += 1
            logger.debug(f"跳过旧文件: {os.path.basename(file_path)} - {file_mtime}")
            continue
            
        try:
            logger.info(f"分析文件: {os.path.basename(file_path)}")
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()
                account_data = parse_alq_logs(content, account_data)
                processed_files += 1
                
                # 检查数据完整性 - 如果有账号数据，停止处理更多文件
                if account_data:
                    logger.info("找到有效账号数据，停止处理更多文件")
                    break
                    
        except Exception as e:
            logger.error(f"文件解析失败: {file_path} - {str(e)}")
    
    logger.info(f"文件处理完成: 已处理 {processed_files} 个文件, 跳过 {skipped_files} 个")
    return account_data

def generate_table_report(account_data):
    """生成表格格式的统计报告"""
    if not account_data:
        return "⚠️ 未找到有效的账号统计信息", {}
    
    # 计算总计
    totals = {
        'points': 0,
        'lottery_amount': 0.0,
        'articles_read': 0,
        'total_articles': 0,
        'tasks': defaultdict(lambda: {'completed': 0, 'total': 0}),
        'news_tasks': {
            'read': {'success': 0, 'fail': 0},
            'like': {'success': 0, 'fail': 0},
            'share': {'success': 0, 'fail': 0}
        },
        'accounts': len(account_data)
    }
    
    # 汇总所有账号数据
    for data in account_data.values():
        totals['points'] += data['points']
        totals['lottery_amount'] += data['lottery_amount']
        totals['articles_read'] += data['articles_read']
        totals['total_articles'] += data['total_articles']
        
        # 汇总任务数据
        for task_name, task_data in data['tasks'].items():
            totals['tasks'][task_name]['completed'] += task_data['completed']
            totals['tasks'][task_name]['total'] += task_data['total']
        
        # 汇总新闻任务数据
        for task_type in ['read', 'like', 'share']:
            totals['news_tasks'][task_type]['success'] += data['news_tasks'][task_type]['success']
            totals['news_tasks'][task_type]['fail'] += data['news_tasks'][task_type]['fail']
    
    # 构建表格报告
    report_lines = [
        "📊 爱路桥任务每日统计报告",
        "=" * 60,
        "📈 全局汇总:"
    ]
    
    # 添加全局汇总信息
    report_lines.append(f"    👥 总账号数: {totals['accounts']}个")
    report_lines.append(f"    💰 总积分: {totals['points']}")
    report_lines.append(f"    🎫 总抽奖金额: {totals['lottery_amount']:.2f}元")
    report_lines.append(f"    📚 文章阅读: {totals['articles_read']}/{totals['total_articles']}篇")
    
    # 添加任务汇总
    report_lines.append("\n📋 任务完成情况:")
    for task_name, task_data in totals['tasks'].items():
        report_lines.append(f"    📌 {task_name}: {task_data['completed']}/{task_data['total']} (完成率: {task_data['completed']/task_data['total']*100:.1f}%)")
    
    # 添加新闻任务汇总
    report_lines.append("\n📰 新闻任务执行情况:")
    task_names = {'read': '阅读新闻', 'like': '点赞新闻', 'share': '转发新闻'}
    for task_type, task_name in task_names.items():
        success = totals['news_tasks'][task_type]['success']
        fail = totals['news_tasks'][task_type]['fail']
        total = success + fail
        rate = success / total * 100 if total > 0 else 0
        report_lines.append(f"    {task_name}: ✅{success}次, ❌{fail}次 (成功率: {rate:.1f}%)")
    
    report_lines.append("=" * 60)
    report_lines.append("\n📋 账号详情:")
    
    # 添加表格标题
    report_lines.append("\n账    号".ljust(20) + "积分".center(10) + "抽奖金额".center(15) + "文章阅读".center(15))
    report_lines.append("─" * 60)
    
    # 添加每个账号的信息
    for account, data in account_data.items():
        # 格式化账号信息
        account_display = f"🔷 {account}" if len(account) < 15 else f"🔷 ...{account[-11:]}"
        
        # 格式化积分
        points_display = f"💰 {data['points']}".center(10)
        
        # 格式化抽奖金额
        lottery_display = f"🎫 {data['lottery_amount']:.2f}元".center(15)
        
        # 格式化文章阅读
        articles_display = f"📚 {data['articles_read']}/{data['total_articles']}".center(15)
        
        # 添加账号行
        report_lines.append(
            account_display.ljust(20) + 
            points_display + 
            lottery_display + 
            articles_display
        )
        
        # 添加分隔线
        report_lines.append("─" * 60)
    
    # 添加报告时间
    report_lines.append("=" * 60)
    report_lines.append(f"📅 报告生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    
    return "\n".join(report_lines), totals

def push_plus_notify(title, content):
    """
    使用PUSH_PLUS推送通知
    """
    token = os.environ.get('PUSH_PLUS_TOKEN')
    if not token:
        logger.error("未找到PUSH_PLUS_TOKEN环境变量，无法发送通知")
        return False
    
    try:
        # PUSH_PLUS API地址
        url = "http://www.pushplus.plus/send"
        
        # 请求数据
        data = {
            "token": token,
            "title": title,
            "content": content,
            "template": "txt"
        }
        
        # 发送请求
        response = requests.post(url, json=data)
        result = response.json()
        
        if response.status_code == 200 and result.get("code") == 200:
            logger.info("PUSH_PLUS通知发送成功")
            return True
        else:
            logger.error(f"PUSH_PLUS通知发送失败: {result.get('msg', '未知错误')}")
            return False
    except Exception as e:
        logger.error(f"发送PUSH_PLUS通知时出错: {str(e)}")
        return False

def send_notification(title, content):
    """
    发送通知
    """
    # 使用PUSH_PLUS发送通知
    if push_plus_notify(title, content):
        return True
    
    logger.warning("PUSH_PLUS通知发送失败，尝试使用其他通知方式")
    # 这里可以添加其他通知方式，如sendNotify.js
    return False

def main():
    """主函数"""
    task_start = datetime.now()
    logger.info("开始爱路桥任务统计")
    
    try:
        # 步骤1: 处理日志目录
        account_data = process_log_directories()
        
        # 步骤2: 生成报告
        report, totals = generate_table_report(account_data)
        
        # 步骤3: 输出报告
        logger.info("\n" + report)
        
        # 步骤4: 保存报告到文件
        os.makedirs(os.path.dirname(REPORT_FILE), exist_ok=True)
        with open(REPORT_FILE, 'w', encoding='utf-8') as f:
            f.write(report)
        logger.info(f"统计报告已保存至: {REPORT_FILE}")
        
        # 步骤5: 发送通知
        if account_data:
            # 创建通知标题
            title = f"爱路桥任务统计 ({len(account_data)}账号)"
            
            # 创建通知内容
            notify_content = [
                "📊 爱路桥任务每日统计报告",
                "=" * 40,
                "📈 全局汇总:",
                f"    👥 总账号数: {totals['accounts']}个",
                f"    💰 总积分: {totals['points']}",
                f"    🎫 总抽奖金额: {totals['lottery_amount']:.2f}元",
                f"    📚 文章阅读: {totals['articles_read']}/{totals['total_articles']}篇",
                "=" * 40,
                "\n📋 账号详情:"
            ]
            
            # 添加表格标题
            notify_content.append("\n账    号".ljust(20) + "积分".center(10) + "抽奖金额".center(15) + "文章阅读".center(15))
            notify_content.append("─" * 40)
            
            # 添加每个账号的信息
            for account, data in account_data.items():
                # 格式化账号信息
                account_display = f"🔷 {account}" if len(account) < 15 else f"🔷 ...{account[-11:]}"
                
                # 格式化积分
                points_display = f"💰 {data['points']}".center(10)
                
                # 格式化抽奖金额
                lottery_display = f"🎫 {data['lottery_amount']:.2f}元".center(15)
                
                # 格式化文章阅读
                articles_display = f"📚 {data['articles_read']}/{data['total_articles']}".center(15)
                
                # 添加账号行
                notify_content.append(
                    account_display.ljust(20) + 
                    points_display + 
                    lottery_display + 
                    articles_display
                )
                
                # 添加分隔线
                notify_content.append("─" * 40)
            
            # 添加报告时间
            notify_content.append("=" * 40)
            notify_content.append(f"📅 报告生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
            
            # 发送通知
            send_notification(title, "\n".join(notify_content))
        else:
            logger.warning("无有效数据，跳过通知发送")
        
        # 计算任务耗时
        task_duration = datetime.now() - task_start
        logger.info(f"任务总耗时: {task_duration.total_seconds():.2f} 秒")
        
        # 返回退出码（0表示成功）
        return 0
    except Exception as e:
        logger.exception(f"任务执行失败: {str(e)}")
        # 发送错误通知
        error_title = "爱路桥任务统计失败"
        error_content = f"任务执行出错: {str(e)}\n\n请查看日志获取详细信息"
        send_notification(error_title, error_content)
        return 1

if __name__ == "__main__":
    import sys
    from datetime import datetime
    
    # 设置时区为北京时间
    os.environ['TZ'] = 'Asia/Shanghai'
    
    exit_code = main()
    sys.exit(exit_code)